package com.hr.service.impl;

import com.hr.entity.Menu;
import com.hr.entity.Role;
import com.hr.entity.RoleMenu;
import com.hr.enums.ExceptionEnum;
import com.hr.exception.MyException;
import com.hr.mapper.MenuMapper;
import com.hr.mapper.RoleMenuMapper;
import com.hr.service.MenuService;
import com.hr.vo.MenuVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Transactional
@Service
public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public void addMenu(Menu menu) {
        menuMapper.addMenu(menu);
    }

    @Override
    public void deleteMenu(Integer menuId) {
        List<Menu> children = menuMapper.getEnabledChildMenuListByParentId(menuId);
        if(CollectionUtils.isEmpty(children)){
            menuMapper.deleteMenu(menuId);
            // 删除关联表
            List<Menu> childMenus = menuMapper.getMenuListByParentId(menuId);
            deleteRoleMenu(childMenus);
        }else{
            // 有下级菜单不可删除
            throw new MyException(ExceptionEnum.MENU_DELTE_ERROR);
        }
    }

    @Override
    public void updateMenu(Menu menu) {
        menuMapper.updateMenu(menu);
    }

    @Override
    public List<Menu> getMenuList() {
        return menuMapper.getMenuList();
    }

    @Override
    public List<Menu> getEnabledChildMenuList(Integer parentId) {
        return menuMapper.getEnabledChildMenuListByParentId(parentId);
    }

    @Override
    public Menu getMenuById(Integer id) {
        return menuMapper.getMenuById(id);
    }

    @Override
    public List<MenuVO> getMenuListWithAuthByRoleId(Integer roleId) {
        List<Menu> menuList = menuMapper.getMenuList();
        List<RoleMenu> roleMenuList = roleMenuMapper.getRoleMenuListByRoleId(roleId);
        List<Integer> ids = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        List<MenuVO> menuVOList = createMenuVOList(menuList, ids);
        return menuVOList;
    }

    /**
     * 递归创建List<MenuVO>
     * @param menuList
     * @param ids
     * @return
     */
    private List<MenuVO> createMenuVOList(List<Menu> menuList, List<Integer> ids){
        if(!CollectionUtils.isEmpty(menuList)){
            List<MenuVO> menuVOList = new ArrayList<>();
            for (Menu menu : menuList) {
                MenuVO menuVO = new MenuVO();
                menuVO.setId(menu.getId());
                menuVO.setTitle(menu.getTitle());
                menuVO.setSpread(true);
                if(ids.contains(menu.getId())){
                    menuVO.setChecked(true);
                }else{
                    //基础类型才有默认值
                    menuVO.setChecked(false);
                }
                menuVO.setChildren(createMenuVOList(menu.getChildren(), ids));
                menuVOList.add(menuVO);
            }
            return menuVOList;
        }else{
            return new ArrayList<>();
        }
    }

    /**
     * 递归删除RoleMenu
     * @param menus
     */
    private void deleteRoleMenu(List<Menu> menus){
        if(!CollectionUtils.isEmpty(menus)){
            for (Menu menu : menus){
                roleMenuMapper.disableRoleMenuByMenuId(menu.getId());
                List<Menu> children = menu.getChildren();
                deleteRoleMenu((children));
            }
        }
    }
}
